<template>
  <div class="process-definitions">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>流程定义管理</span>
          <el-button type="primary" @click="showDeployDialog">
            部署新流程
          </el-button>
        </div>
      </template>
      
      <el-table :data="definitions" v-loading="loading" style="width: 100%">
        <el-table-column prop="name" label="流程名称" />
        <el-table-column prop="key" label="流程标识" />
        <el-table-column prop="version" label="版本" width="100" />
        <el-table-column prop="description" label="描述" />
        <el-table-column prop="createdAt" label="创建时间" width="180">
          <template #default="{ row }">
            {{ formatDateTime(row.createdAt) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200">
          <template #default="scope">
            <el-button-group>
              <el-button 
                type="primary"
                size="small" 
                @click="handleStart(scope.row)"
              >
                发起
              </el-button>
              <el-button size="small" @click="handleEdit(scope.row)">
                编辑
              </el-button>
              <el-button size="small" @click="handleView(scope.row)">
                查看
              </el-button>
              <el-button type="danger" size="small" @click="handleDelete(scope.row)">
                删除
              </el-button>
            </el-button-group>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 部署/编辑对话框 -->
    <el-dialog 
      v-model="deployDialogVisible" 
      custom-class="process-edit-dialog"
      :fullscreen="false"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="false"
      width="95%"
      @closed="handleDialogClose">
      <template #header>
        <div class="dialog-header">
          <span>部署新流程</span>
          <el-button @click="handleDeployBack">
            <el-icon><Back /></el-icon>返回列表
          </el-button>
        </div>
      </template>
      
      <el-form :model="deployForm" ref="deployFormRef" label-width="100px">
        <el-form-item label="流程标识" prop="key" :rules="[
          { required: true, message: '请输入流程标识', trigger: 'blur' }
        ]">
          <el-input v-model="deployForm.key" placeholder="请输入流程标识"></el-input>
        </el-form-item>
      </el-form>
      
      <BpmnDesigner 
        ref="designerRef" 
        @save="handleDesignerSave" 
        :xml="defaultBpmnXml"
        :readonly="false"
        :process-id="''"
      />
    </el-dialog>

    <!-- 查看流程图对话框 -->
    <el-dialog 
      v-model="viewDialogVisible" 
      title="查看流程图" 
      width="90%"
      :fullscreen="false"
      class="process-edit-dialog">
      <bpmn-designer 
        v-if="viewDialogVisible"
        :process-id="currentProcess?.id"
        :readonly="true"
      />
    </el-dialog>

    <!-- 编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="currentProcess ? '编辑流程' : '新建流程'"
      width="90%"
      :fullscreen="false"
      class="process-edit-dialog">
      <bpmn-designer
        v-if="dialogVisible"
        :process-id="currentProcess?.id"
        :readonly="false"
        @save="handleSave" />
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import BpmnJS from 'bpmn-js'
import { getProcessDefinitions, deployProcessDefinition, deleteProcessDefinition, updateProcessDefinition } from '@/api/process'
import BpmnDesigner from '@/components/BpmnDesigner.vue'
import request from '@/utils/request'
import { Back } from '@element-plus/icons-vue'
import { useRouter } from 'vue-router'

const loading = ref(false)
const definitions = ref([])
const deployDialogVisible = ref(false)
const viewDialogVisible = ref(false)
const deployFormRef = ref(null)
const bpmnViewer = ref(null)
const currentBpmnXml = ref('')
const designerRef = ref(null)
const dialogVisible = ref(false)
const currentProcess = ref(null)
const defaultBpmnXml = ref('')
const router = useRouter()

const deployForm = ref({
  key: '',
  file: null
})

const saving = ref(false)

const loadDefinitions = async () => {
  loading.value = true
  try {
    const response = await getProcessDefinitions()
    definitions.value = response.data
  } catch (error) {
    ElMessage.error('加载流程定义失败')
  } finally {
    loading.value = false
  }
}

const showDeployDialog = () => {
  deployForm.value = {
    key: '',
    file: null
  }
  defaultBpmnXml.value = ''
  deployDialogVisible.value = true
}

const handleFileChange = (file) => {
  deployForm.value.file = file.raw
}

const handleDesignerSave = async (xml) => {
  try {
    await request.post('/process-definitions', {
      name: deployForm.value.key,
      xml: xml
    });
    
    ElMessage.success('部署成功');
    deployDialogVisible.value = false;
    loadDefinitions();
  } catch (error) {
    console.error('部署失败:', error);
    ElMessage.error('部署失败');
  }
}

const handleDelete = async (row) => {
  try {
    await ElMessageBox.confirm('确定要删除该流程定义吗？', '提示', {
      type: 'warning'
    })
    
    await request.delete(`/process-definitions/${row.id}`, {
      params: {
        processId: row.id
      }
    });
    
    ElMessage.success('删除成功')
    loadDefinitions()
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除失败:', error);
      ElMessage.error('删除失败')
    }
  }
}

const handleView = (row) => {
  currentProcess.value = row
  viewDialogVisible.value = true
}

const handleEdit = (row) => {
  currentProcess.value = row
  dialogVisible.value = true
}

const handleDialogClose = () => {
  deployForm.value = {
    key: '',
    file: null
  }
}

const formatDateTime = (dateTime) => {
  if (!dateTime) return ''
  return new Date(dateTime).toLocaleString()
}

const handleSave = async (xml) => {
  saving.value = true
  try {
    if (currentProcess.value) {
      // 更新流程
      const formData = new FormData()
      formData.append('key', currentProcess.value.key)
      formData.append('file', new Blob([xml], { type: 'text/xml' }))
      await updateProcessDefinition(currentProcess.value.id, formData)
      ElMessage.success('保存成功')
      dialogVisible.value = false
      loadDefinitions()
    }
  } catch (error) {
    console.error('保存失败:', error)
    ElMessage.error('保存失败')
  } finally {
    saving.value = false
  }
}

const handleDeployBack = () => {
  ElMessageBox.confirm('确定要返回列表吗？未保存的更改将会丢失', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    deployDialogVisible.value = false
  }).catch(() => {})
}

const handleStart = (row) => {
  if (!row.key) {
    ElMessage.error('流程标识不能为空')
    return
  }
  router.push({
    name: 'ProcessStart',
    params: { processKey: row.key }
  })
}

onMounted(() => {
  loadDefinitions()
})
</script>

<style scoped>
.process-definitions {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.bpmn-viewer {
  height: 600px;
  width: 100%;
}

.deploy-dialog :deep(.el-dialog__body) {
  height: calc(100vh - 120px);
  padding: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.deploy-dialog :deep(.el-form) {
  padding: 15px;
  background-color: #fff;
  border-bottom: 1px solid #dcdfe6;
  flex-shrink: 0;
}

.deploy-dialog :deep(.el-dialog__header) {
  padding: 15px;
  margin-right: 0;
  border-bottom: 1px solid #dcdfe6;
  background-color: #fff;
  flex-shrink: 0;
}

.deploy-dialog :deep(.el-dialog__footer) {
  border-top: 1px solid #dcdfe6;
  padding: 15px;
  background-color: #fff;
  flex-shrink: 0;
}

.deploy-dialog :deep(.bpmn-designer) {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 600px;
}

.deploy-dialog :deep(.container) {
  min-height: 600px;
  height: 100%;
}

.deploy-dialog :deep(.canvas) {
  min-height: 600px;
  height: 100%;
}

.view-dialog :deep(.el-dialog__body) {
  height: 80vh;
  padding: 0;
  overflow: hidden;
}

.process-edit-dialog :deep(.el-dialog__body) {
  padding: 0;
  height: calc(75vh - 108px);
  overflow: hidden;
}

.process-edit-dialog :deep(.el-dialog__header) {
  margin: 0;
  padding: 12px 15px;
  border-bottom: 1px solid #dcdfe6;
  height: 44px;
  box-sizing: border-box;
}

.process-edit-dialog :deep(.el-dialog) {
  margin-top: 12.5vh !important;
  margin-bottom: 12.5vh;
  height: 75vh;
  display: flex;
  flex-direction: column;
}

.process-edit-dialog :deep(.el-dialog__footer) {
  border-top: 1px solid #dcdfe6;
  padding: 12px 15px;
  background-color: #fff;
  flex-shrink: 0;
  height: 64px;
  box-sizing: border-box;
}

.process-edit-dialog :deep(.bpmn-designer) {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.process-edit-dialog :deep(.container) {
  flex: 1;
  min-height: 0;
}

.process-edit-dialog :deep(.canvas) {
  height: 100%;
}

.dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.process-edit-dialog :deep(.el-form) {
  padding: 15px;
  background-color: #fff;
  border-bottom: 1px solid #dcdfe6;
}
</style> 